package com.yupi.springbootinit.statemachine.rule.impl;

import com.yupi.springbootinit.statemachine.core.StateContext;
import com.yupi.springbootinit.statemachine.rule.BusinessRule;
import com.yupi.springbootinit.statemachine.rule.RuleValidationResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * 工序实例业务规则实现
 * 包含工序执行过程中的各种业务规则
 */
@Slf4j
@Component
public class ProcessInstanceBusinessRules {
    
    /**
     * 工序开始规则：检查前序工序是否完成
     */
    public static class ProcessStartRule implements BusinessRule {
        
        @Override
        public String getRuleName() {
            return "PROCESS_START_RULE";
        }
        
        @Override
        public String getDescription() {
            return "验证工序开始前的前置条件，确保前序工序已完成";
        }
        
        @Override
        public RuleValidationResult validate(StateContext context) {
            Long processInstanceId = context.getEntityId();
            
            // 检查前序工序是否完成
            // 实际应用中应该查询工序依赖关系和前序工序状态
            if (processInstanceId == null) {
                return RuleValidationResult.failure("工序实例ID不能为空", "PROCESS_INSTANCE_ID_NULL");
            }
            
            // 模拟检查前序工序状态
            // 这里应该实现具体的前序工序检查逻辑
            
            log.debug("工序开始规则验证通过: {}", processInstanceId);
            return RuleValidationResult.success();
        }
        
        @Override
        public int getPriority() {
            return 10;
        }
    }
    
    /**
     * 工序完成规则：检查工序执行结果
     */
    public static class ProcessCompletionRule implements BusinessRule {
        
        @Override
        public String getRuleName() {
            return "PROCESS_COMPLETION_RULE";
        }
        
        @Override
        public String getDescription() {
            return "验证工序完成时的条件，确保工序执行结果符合要求";
        }
        
        @Override
        public RuleValidationResult validate(StateContext context) {
            Long processInstanceId = context.getEntityId();
            
            // 检查工序执行时间是否合理
            // 检查工序参数是否填写完整
            // 检查是否需要质检
            
            if (processInstanceId == null) {
                return RuleValidationResult.failure("工序实例ID不能为空", "PROCESS_INSTANCE_ID_NULL");
            }
            
            // 模拟检查工序执行数据
            Object processData = context.getParameter("processData", Object.class);
            if (processData == null) {
                return RuleValidationResult.failure("工序执行数据不完整", "PROCESS_DATA_INCOMPLETE");
            }
            
            log.debug("工序完成规则验证通过: {}", processInstanceId);
            return RuleValidationResult.success();
        }
        
        @Override
        public int getPriority() {
            return 20;
        }
    }
    
    /**
     * 外协工序规则：检查外协相关条件
     */
    public static class OutsourcingProcessRule implements BusinessRule {
        
        @Override
        public String getRuleName() {
            return "OUTSOURCING_PROCESS_RULE";
        }
        
        @Override
        public String getDescription() {
            return "验证外协工序的特殊条件";
        }
        
        @Override
        public RuleValidationResult validate(StateContext context) {
            // 检查外协供应商是否确定
            // 检查外协交付时间是否合理
            // 检查外协质量要求是否明确
            
            Long processInstanceId = context.getEntityId();
            
            // 模拟检查外协信息
            // 实际应用中应该查询外协相关配置
            
            log.debug("外协工序规则验证通过: {}", processInstanceId);
            return RuleValidationResult.success();
        }
        
        @Override
        public int getPriority() {
            return 30;
        }
    }
    
    /**
     * 返工规则：检查返工条件和次数限制
     */
    public static class ReworkRule implements BusinessRule {
        
        @Override
        public String getRuleName() {
            return "REWORK_RULE";
        }
        
        @Override
        public String getDescription() {
            return "验证返工的条件和次数限制";
        }
        
        @Override
        public RuleValidationResult validate(StateContext context) {
            Long processInstanceId = context.getEntityId();
            
            // 检查返工次数是否超过限制
            // 检查返工原因是否明确
            // 检查返工方案是否可行
            
            // 模拟检查返工次数（实际应用中应该查询历史记录）
            int reworkCount = getReworkCount(processInstanceId);
            int maxReworkCount = 3; // 最大返工次数限制
            
            if (reworkCount >= maxReworkCount) {
                return RuleValidationResult.failure(
                    String.format("返工次数已达上限(%d次)，请联系工程部处理", maxReworkCount),
                    "REWORK_LIMIT_EXCEEDED"
                );
            }
            
            log.debug("返工规则验证通过: {} (返工次数: {})", processInstanceId, reworkCount);
            return RuleValidationResult.success();
        }
        
        @Override
        public int getPriority() {
            return 40;
        }
        
        /**
         * 模拟获取返工次数
         */
        private int getReworkCount(Long processInstanceId) {
            // 实际应用中应该查询数据库获取返工历史
            return processInstanceId != null ? (int)(processInstanceId % 3) : 0;
        }
    }
}